<?php

namespace app\apisell\controller\xcx;

use app\apiadmin\controller\live\UnionApp;
use app\apiadmin\controller\live\UnionAppFuWuShang;
use app\apisell\service\Log\LogNumService;
use app\apisell\service\order\OrderService;
use app\apisell\service\Payment\PaymentService;
use app\common\controller\BaseController;
use app\common\miniProgram\MiniProgram;
use app\common\utils\Curl;
use app\common\utils\Res;
use DateTime;
use DateTimeZone;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;
use WeChatPay\Builder;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
use WeChatPay\Util\PemUtil;

class Payment extends BaseController
{
    /**
     * 获取订单信息并处理微信支付相关逻辑
     *
     * 该方法从请求中获取订单参数，查询相关数据，并准备微信支付所需的数据
     * 它创建一个订单对象，设置支付金额，过期时间等，并调用微信支付接口获取预支付ID
     * 最后，它组合数据以供前端调用，包括签名验证
     */
    public function orderInfo()
    {
        try {
            // 获取请求参数
            $params = $this->request->post();
            // 提取订单类型 1为商品订单 2为拼团订单
            $order_type =  $params['order_type'];
            // 获取当前用户ID
            $user_id = $this->request->id;
            if ($order_type == 1){
                // 提取订单ID和商品ID
                $order_id = $params['order_id'];
                // 提取商品ID
                $goods_id = $params['goods_id'];
                //提取购买数量 
                $number = intval($params['number']);
                // 查询订单信息，包括订单编号
                $orderInfo = Db::table('xh_sell_order')->where('id',$order_id)->find();
                if (empty($orderInfo)) {
                    return Res::error('订单不存在');
                }
                
                $ip = $_SERVER['REMOTE_ADDR'];
                $resGoods = Db::table('xh_sell_order_goods')->where('order_id',$order_id)->find();
                $openid = Db::table('xh_sell_user')->where('id',$user_id)->value('openid');
                if (!$openid) {
                    throw new Exception('用户未绑定微信', 500);
                }
                $account['sp_appid'] = 'wx9731dda09a3456a6';
                $account['sp_mchid'] = '1608687804';
                $account['sub_appid'] = 'wxc2b4ee4576994f04';
                $account['sub_mchid'] = '1695828795';

                $arr = [
                    'account' => $account,
                    'openid' => $openid,
                    'number' => $resGoods['number'],
                    'price' => $resGoods['price'],
                    'title' => $resGoods['title'],
                    'goods_id' => $resGoods['goods_id'],
                    'order_no' => $orderInfo['order_no'],
                    'time' =>  time(),
                    'order_id' => $order_id,
                    'user_id' => $user_id,
                    'ip' => $ip,
                    'order_type' => $order_type,

                ];

                $data = self::createPrepayId($arr);
            }elseif ($order_type == 2){ //拼团订单
                // 提取订单ID和商品ID
                $order_id = $params['order_id'];
                // 提取商品ID
                $goods_id = $params['goods_id'];
                //提取购买数量 
                $number = intval($params['number']);
                //拼团SKUID
                $goods_sku_id = intval($params['goods_sku_id']);
                // 查询拼团订单信息，包括订单编号
                $orderInfo = Db::table('xh_sell_groups_order')->where('id',$order_id)->find();
                if (empty($orderInfo)) {
                    return Res::error('订单不存在');
                }
                // 查询拼团订单规格信息，包括价格和标题
                $goodsSkuId = Db::table('xh_sell_groups_goods_spec')->where('id',$goods_sku_id)->find();
                if (empty($goodsSkuId)) {
                    return Res::error('拼团商品规格不存在');
                }
                $ip = $_SERVER['REMOTE_ADDR'];
                $resGoods = Db::table('xh_sell_groups_order_goods')->where('order_id', $order_id)->find();
                if (empty($resGoods)) {
                    return Res::error('拼团商品信息不存在');
                }
                $openid = Db::table('xh_sell_user')->where('id', $user_id)->value('openid');
                if (empty($openid)) {
                    return Res::error('用户未绑定微信');
                }
                $account['sp_appid'] = 'wx9731dda09a3456a6';
                $account['sp_mchid'] = '1608687804';
                $account['sub_appid'] = 'wxc2b4ee4576994f04';
                $account['sub_mchid'] = '1695828795';

                $arr = [
                    'account' => $account,
                    'openid' => $openid,
                    'number' => $resGoods['number'],
                    'price' => $resGoods['price'],
                    'title' => $resGoods['title'],
                    'goods_id' => $resGoods['goods_id'],
                    'order_no' => $orderInfo['order_no'],
                    'time' => time(),
                    'order_id' => $order_id,
                    'user_id' => $user_id,
                    'ip' => $ip,
                    'order_type' => $order_type,

                ];

                $data = self::createPrepayId($arr);
            }
           
            return Res::ok($data);

        } catch (\Exception $e) {
            $err['code'] = $e->getCode();
            $err['msg'] = $e->getMessage();
            $err['ling'] = $e->getLine();
            return Res::error($err);

        }
    }

    /**
     * @author: ch
     * @Description: 生成微信支付订单预下单ID
     * @param {*} $arr->account         商户信息
     * @param {*} $arr->openid          用户openid
     * @param {*} $arr->number          数量
     * @param {*} $arr->price           金额  单位：分
     * @param {*} $arr->title           商品名称
     * @param {*} $arr->goods_id        商品ID
     * @param {*} $arr->out_trade_no    订单号
     * @param {*} $arr->time            下单时间  时间戳
     * @param {*} $arr->order_no        订单号
     * @param {*} $arr->user_id         用户ID
     * @param {*} $arr->ip              付款IP
     * @Date: 2024-05-22 18:34:38
     */
    public static function createPrepayId($arr)
    {
        try {
            // 提取订单ID和商品ID
            $account = $arr['account'];
            $order_id = $arr['order_id'];
            $goods_id = $arr['goods_id'];
            $order_no = $arr['order_no'];
            $number = intval($arr['number']);
            $user_id = $arr['user_id'];
            $openid = $arr['openid'];
            $price = $arr['price'];
            $title = $arr['title'];
            $ip = $arr['ip'];
            $time = $arr['time'];
            $order_type = $arr['order_type'];
            // 设置微信支付API URL
            $url = 'https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi';
            
            // 创建DateTime对象
            $dateTime = new DateTime(date('Y-m-d H:i:s', $time));

            // 设置时区，如果需要的话
            $dateTime->setTimezone(new DateTimeZone('Asia/Shanghai'));

            // 生成RFC3339格式的时间字符串
            $time_expire = $dateTime->format(DateTime::RFC3339);
            
            // 初始化JSON数据数组，用于微信支付请求
            $json = [];
            $json['sp_appid'] = $account['sp_appid'];  //【服务商应用ID】 由微信生成的应用ID，全局唯一。请求基础下单接口时请注意AppID的应用属性，例如公众号场景下，需使用应用属性为公众号的服务号AppID
            $json['sp_mchid'] = $account['sp_mchid'];  //【服务商户号】 服务商户号，由微信支付生成并下发
            $json['sub_appid'] = $account['sub_appid'];  //【子商户/二级商户应用ID】 子商户/二级商户在开放平台申请的应用AppID,若sub_openid有传的情况下，sub_appid必填，且sub_appid需与sub_openid对应
            $json['sub_mchid'] = $account['sub_mchid'];  //【子商户号/二级商户号】 子商户/二级商户的商户号，由微信支付生成并下发。
            $json['description'] = $title;  //【商品描述】 商品描述
            $json['out_trade_no'] = $order_no;
            $json['time_expire'] = $time_expire;
            // 用户ID/openID/订单ID/商品ID
            $json['attach'] = $user_id.'_'.$openid.'_'.$order_id.'_'.$goods_id;
            $json['notify_url'] = env('Live.api_host') . '/apisell/xcx/pay/notify';
            $json['amount'] = [
                'total' => intval($price),
                'currency' => 'CNY',
            ];
            $json['payer'] = [
                'sub_openid' => $openid
            ];
            $json['scene_info'] = [
                'payer_client_ip' => $ip,
                'store_info' => [
                    'id' => '0001',
                ]
            ];
            $result = UnionAppFuWuShang::client_post($url, $json);

            $data = array();
            $data['appId'] = $account['sub_appid']; //商户申请的公众号对应的AppID，由微信支付生成，可在公众号后台查看。若下单时传了sub_appid，可为sub_appid的值。
            $data['timeStamp'] = $time;
            $data['nonceStr'] = Formatter::nonce();
            $data['package'] = 'prepay_id=' . json_decode($result['body'], true)['prepay_id'];
            $data['signType'] = 'RSA';
            $data['paySign'] = UnionAppFuWuShang::makeSign($data['appId'], $data['timeStamp'], $data['nonceStr'], $data['package']); //签名，使用字段AppID、timeStamp、nonceStr、package计算得出的签名值
            file_put_contents("./wechatpay_fuwushang_notify.txt", date('Y-m-d H:i:s', time()) . $openid . '----openid----' . json_encode($data) . "\n", FILE_APPEND);
            // 记录订单支付信息
            $dataLog = [
                'user_id' => $user_id,
                'order_id' => $order_id,
                'order_no' => $order_no,
                'pay_type' => 1,
                'number' => $number,
                'type' => $order_type,
                'price' => $price,
                'order_price' => $price,
                'actual_payment' => $price,
                'create_time' => date('Y-m-d H:i:s'),

            ];
            Db::table('xh_sell_order_pay')->insert($dataLog);

            // 返回组合后的数据
            return $data;
        } catch (\Exception $e) {
            $err['code'] = $e->getCode();
            $err['msg'] = $e->getMessage();
            $err['ling'] = $e->getLine();
            return $err;

        }
    }

    /**
     * 处理微信支付通知的函数
     *
     * 本函数主要用于验证微信支付的通知，并在验证通过后处理订单状态
     * 它通过验证通知的签名、时间戳和偏移量来确保通知的合法性和时效性
     * 验证通过后，函数会解析通知内容，解密敏感信息，并记录通知详情
     * 最后，调用另一个函数更新订单状态
     */
    public function notify()
    {
        // 获取微信支付通知的签名、时间戳、随机串等信息
        $inWechatpaySignature = $_SERVER['HTTP_WECHATPAY_SIGNATURE']; // 请根据实际情况获取
        $inWechatpayTimestamp = $_SERVER['HTTP_WECHATPAY_TIMESTAMP']; // 请根据实际情况获取
        $inWechatpaySerial = ''; // 请根据实际情况获取
        $inWechatpayNonce = $_SERVER['HTTP_WECHATPAY_NONCE']; // 请根据实际情况获取
        $inBody = file_get_contents('php://input');
        // 请根据实际情况获取，例如: file_get_contents('php://input');
    
        // 设置APIv3密钥，用于解密通知内容
        $apiv3Key = 'bd6dde34c6eab25a2bfc5c9ce8e5de37'; // 在商户平台上设置的APIv3密钥

        $platformCertificateFilePath = 'file:///data/mmc/api/app/apiadmin/keys/fuwushang_Keys/wechatpay_1EF4FF0FD715C8F10A4DB17E274CFF531CCC78A4.pem';
        // 根据通知的平台证书序列号，查询本地平台证书文件，
        // 假定为 `/path/to/wechatpay/inWechatpaySerial.pem`
        $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
        // 检查通知时间偏移量，允许5分钟之内的偏移
        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int) $inWechatpayTimestamp);
        $verifiedStatus = Rsa::verify(
            // 构造验签名串
            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
            $inWechatpaySignature,
            $platformPublicKeyInstance
        );
        // 如果时间和签名验证都通过，则进一步处理通知内容
        if ($timeOffsetStatus && $verifiedStatus) {
            // 转换通知的JSON文本消息为PHP Array数组
            $inBodyArray = (array) json_decode($inBody, true);
            // 提取加密的通知内容，并解密
            $ciphertext = $inBodyArray['resource']['ciphertext'];
            $nonce = $inBodyArray['resource']['nonce'];
            $associated_data = $inBodyArray['resource']['associated_data'];
            // 加密文本消息解密
            $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $associated_data);
            $id = Db::table('xh_sell_refund_log')->insertGetId(['info'=>$inBodyResource, 'create_time'=>date('Y-m-d H:i:s')]);
            // 把解密后的文本转换为PHP Array数组
            $inBodyResourceArray = (array) json_decode($inBodyResource, true);
            // 记录解密后的通知内容到文件
            file_put_contents("./wechatpay_notify.txt", date('Y-m-d H:i:s', time()) . '----支付回调通知----' . $inBodyResource . "\n", FILE_APPEND);
             
            // 处理普通订单
            self::updateOrder($inBodyResourceArray, $id);
           //处理拼团订单
            self::updateGroupsOrder($inBodyResourceArray,$id);
        }
    }
    /**
     * 更新订单状态和处理支付结果
     *
     * @param array $res 支付响应数据，包含交易号、交易状态等信息
     * @param int $id 退款日志ID，用于更新退款日志表
     */
    private static function updateOrder($res, $id)
    {
        try {
            // 提取支付响应中的关键信息
            $transaction_id = $res['transaction_id']; //交易号
            $out_trade_no = $res['out_trade_no'];
            $trade_state = $res['trade_state']; //交易状态，枚举值： SUCCESS：支付成功 REFUND：转入退款 NOTPAY：未支付
            // 更新退款日志表中的订单号和交易号
            Db::table('xh_sell_refund_log')->where('id', $id)->update(['order_no'=>$out_trade_no,'transaction_id'=>$transaction_id]);
            // 处理支付成功时间，转换为时间戳
            $dateTimeString = $res['success_time'];
            // 创建DateTime对象
            $dateTime = new DateTime($dateTimeString);
            // 设置时区
            $timeZone = new DateTimeZone('Asia/Shanghai'); // 或者使用 '+08:00' 替换
            $dateTime->setTimeZone($timeZone);
            // 转换为时间戳
            $timestamp = $dateTime->getTimestamp(); //支付成功时间
            
            // 查询订单信息
            $resInfo = Db::table('xh_sell_order')->where(['order_no'=>$out_trade_no])->alias('a')
                ->leftJoin('xh_sell_order_goods b','a.id=b.order_id')
                ->field('a.*,b.goods_id')
                ->find();
            
            // 如果支付状态为成功，则进行佣金分配和订单状态更新
            if($trade_state == 'SUCCESS'){
                // 返回成功信息
                echo '{code:"200",message:"成功"}';
                
                // 更新订单状态
                Db::table('xh_sell_order')->where(['order_no'=>$out_trade_no])->update(['state'=>3,'pay_time'=>date('Y-m-d H:i:s',$timestamp)]);
                // 更新订单支付状态和支付时间
                Db::table('xh_sell_order_pay')->where(['order_no'=>$out_trade_no])->update(['pay_state'=>1,'trade_no'=>$transaction_id,'pay_time'=>$timestamp,'update_time'=>date('Y-m-d H:i:s',time())]);

                // 同步订单
                OrderService::syncXhOrder($resInfo['id']);
                // 绑定用户到推广人
                PaymentService::setUserToPopu($resInfo['user_id'], $resInfo['belongs_popu_user_id']);
                // 更新佣金分配
                if ($resInfo['belongs_popu_user_id'] > 0) {
                    self::updateCommission($resInfo);
                }
            } else if ($trade_state == 'CLOSED') {
                // 返回失败信息
                echo '{code:"FAIL",message:"失败"}';
                // 如果交易关闭，更新订单状态（已注释）
                Db::table('xh_sell_order_pay')->where(['order_no'=>$out_trade_no])->update(['pay_state'=>3,'closed_time'=>date('Y-m-d H:i:s',time())]);
            } else if ($trade_state == 'PAYERROR') {
                // 返回失败信息
                echo '{code:"FAIL",message:"失败"}';
                // 如果支付出错，更新订单状态（已注释）
                //$data = array();
                //$data['trade_state_desc'] = $trade_state_desc;
                //DB::table('xh_siyu_order')->where(array('order_num' => $out_trade_no))->save($data);
            }
        } catch (\Exception $e) {
            // 记录异常信息到退款日志表
            $err = ['info_'=>$e->getMessage().'文件：'.$e->getFile().'行号：'.$e->getLine().'文件栈：'.$e->getTraceAsString()];
            Db::table('xh_sell_refund_log')->where('id', $id)->update($err);
        }
    }
    /**
     * 更新团体订单的状态和处理支付结果
     * 
     * 此函数处理支付响应，更新数据库中的订单状态和退款日志，根据支付状态进行相应的操作
     * 
     * @param array $res 支付响应数组，包含交易信息
     * @param int $id 退款日志的ID，用于更新退款日志表
     */
    private static function  updateGroupsOrder($res,$id)
    {
        try {
            // 提取支付响应中的关键信息
            $transaction_id = $res['transaction_id']; //交易号
            $out_trade_no = $res['out_trade_no'];
            $trade_state = $res['trade_state']; //交易状态，枚举值： SUCCESS：支付成功 REFUND：转入退款 NOTPAY：未支付
            // 更新退款日志表中的订单号和交易号
            Db::table('xh_sell_refund_log')->where('id', $id)->update(['order_no'=>$out_trade_no,'transaction_id'=>$transaction_id]);
            // 处理支付成功时间，转换为时间戳
            $dateTimeString = $res['success_time'];
            // 创建DateTime对象
            $dateTime = new DateTime($dateTimeString);
            // 设置时区
            $timeZone = new DateTimeZone('Asia/Shanghai'); // 或者使用 '+08:00' 替换
            $dateTime->setTimeZone($timeZone);
            // 转换为时间戳
            $timestamp = $dateTime->getTimestamp(); //支付成功时间
    
            // 查询订单信息
            $resInfo = Db::table('xh_sell_groups_order')->alias('a')
                ->field('a.*,b.goods_id,b.actual_payment')
                ->leftJoin('xh_sell_groups_order_goods b','a.id=b.order_id')
                ->leftJoin('xh_sell_popu_user p','a.popu_user_id=p.id')
                ->field('a.*, b.goods_id,b.title as goods_name, b.difference as sku_name, b.price as sku_price, p.popu_name, p.phone as popu_phone')
                ->where('a.order_no', $out_trade_no)
                ->find();
    
            // 如果支付状态为成功，则进行佣金分配和订单状态更新
            if($trade_state == 'SUCCESS'){
                // 返回成功信息
                echo '{code:"200",message:"成功"}';
                
                // 更新订单状态
                Db::table('xh_sell_groups_order')->where(['order_no'=>$out_trade_no])->update(['state'=>4,'paymenttime'=>date('Y-m-d H:i:s',$timestamp)]);
                // 更新订单支付状态和支付时间
                Db::table('xh_sell_order_pay')
                    ->where(['order_no'=>$out_trade_no])
                    ->where('type',2)->update(['pay_state'=>1,'trade_no'=>$transaction_id,'pay_time'=>$timestamp,'update_time'=>date('Y-m-d H:i:s',time())]);
                
                //拼团信息处理
                //更新团员状态为正常参团
                Db::table('xh_sell_groups_team')->where('order_id', $resInfo['id'])->update(['is_del'=>0]);
                //获取团员信息
                $team = Db::table('xh_sell_groups_team')->where('order_id', $resInfo['id'])->find();
                // 更新拼团人数
                Db::table('xh_sell_groups')->where('group_no', $team['group_no'])->inc('join_num')->update();
                // 更新拼团的团状态
                Db::table('xh_sell_groups')->where('group_no', $team['group_no'])->update(['state'=>1]);
                $groups = Db::table('xh_sell_groups')->where('group_no', $team['group_no'])->find();
                //获取团员信息
                $groupTeam = Db::table('xh_sell_groups_team')
                    ->alias('a')
                    ->leftJoin('xh_sell_user u','a.user_id=u.id')
                    ->where('a.group_no', $team['group_no'])
                    ->field('a.*, u.openid,u.nickname')
                    ->select()
                    ->toArray();
                // 判断拼团是否完成
                if ($groups['join_num'] >= $groups['people_num']) {
                    Db::table('xh_sell_groups')->where(['id'=>$groups['id']])->update(['state'=>2]);
                    //获取团长信息
                    $teamInfo = Db::table('xh_sell_user')->where('id', $groups['user_id'])->find();
                    
                    $template_id = env('wx.msg_template1');
                    foreach ($groupTeam as $v){
                        // 发送小程序订阅消息-成团
                        $send_params = [
                            'openid' => $v['openid'],
                            'data' => [
                                'thing16' => ['value' => $resInfo['goods_name']],
                                'amount11' => ['value' => number_format($resInfo['actual_payment'] / 100,2,'.','')],
                                'phrase2' => ['value' => '拼团成功'],
                                'thing3' => ['value' => '恭喜您已成团，联系老师领课吧']
                            ],
                            'nickname' => $v['nickname'],
                            'title' => $resInfo['goods_name'],
                            'order_no' => $resInfo['order_no'],
                        ];
                        MiniProgram::sendTempalteMsg($send_params,$template_id);
                    }
                } else {
                    //剩余时间
                    $now = time();
                    $group_link = Db::table('xh_sell_groups_link')->where('link_yard',$groups['link_yard'])->find();
                    $timestamp = strtotime($groups['createtime']);
                    $hourstamp = $group_link['group_hour'] * 60 * 60;
                    $dateTime = $timestamp + $hourstamp;
                    $shengyu_time = $dateTime - $now;
                    $hours = intval($shengyu_time / 3600);
                    $minutes = intval(($shengyu_time % 3600) / 60);
                    //$sy_time = $hours . '小时' . $minutes . '分钟';
                    $sy_time = sprintf("%02d:%02d", $hours, $minutes).':00';
                    
                    $poor_num = $groups['people_num'] - $groups['join_num'];
                    $template_id = env('wx.msg_template3');
                    $tmp = [
                        'thing6' => ['value' => $resInfo['goods_name']],
                        'time4'  => ['value' => $sy_time],
                        'thing5' => ['value' => '还差'.$poor_num.'人即可成团'],
                        'thing9' => ['value' => '剩余时间不多了，快进入小程序参与拼团吧~']
                    ];
                    if ($poor_num == 2) {
                        $template_id = env('wx.msg_template2');
                        $tmp = [
                            'thing1' => ['value' => $resInfo['goods_name']],
                            'thing2' => ['value' => '还差'.($groups['people_num']-$groups['join_num']).'人即可成团'],
                            'time3'  => ['value' => $sy_time],
                            'thing4' => ['value' => '剩余时间不多了，快进入小程序参与拼团吧~']
                        ];
                    }
                    foreach ($groupTeam as $v){
                        // 发送小程序订阅消息-参团
                        $send_params = [
                            'openid' => $v['openid'],
                            'data' => $tmp,
                            'nickname' => $v['nickname'],
                            'title' => $resInfo['goods_name'],
                            'order_no' => $resInfo['order_no'],
                        ];
                        MiniProgram::sendTempalteMsg($send_params,$template_id);
                    }
                }
               
                //统计拼团数据
                //Db::table('xh_sell_groups_num')->where('group_no', $team['group_no'])->inc('payment_num')->update();
                //Db::table('xh_sell_groups_num')->where('group_no', $team['group_no'])->setInc('groups_order_num');
                //Db::table('xh_sell_groups_num')->where('group_no', $team['group_no'])->setInc('groups_size');
                
                //new统计拼团数据
                LogNumService::setPayLog($resInfo['id']);
                // 同步订单
                OrderService::syncXhGroupsOrder($resInfo['id']);
                // 绑定用户到推广人
                PaymentService::setUserToPopu($resInfo['user_id'], $resInfo['popu_user_id']);
                // 更新佣金分配
                if ($resInfo['group_link_id'] > 0) {
                    self::updateGroupsInfo($resInfo);
                }
            } else if ($trade_state == 'CLOSED') {
                // 返回失败信息
                echo '{code:"FAIL",message:"失败"}';
                // 如果交易关闭，更新订单状态（已注释）
                Db::table('xh_sell_order_pay')
                    ->where(['order_no'=>$out_trade_no])
                    ->where('type',2)->update(['pay_state'=>3,'closed_time'=>date('Y-m-d H:i:s',time())]);
            } else if ($trade_state == 'PAYERROR') {
                // 返回失败信息
                echo '{code:"FAIL",message:"失败"}';
                // 如果支付出错，更新订单状态（已注释）
                //$data = array();
                //$data['trade_state_desc'] = $trade_state_desc;
                //DB::table('xh_siyu_order')->where(array('order_num' => $out_trade_no))->save($data);
            }
        } catch (\Exception $e) {
            // 记录异常信息到退款日志表
            $err = ['info_'=>$e->getMessage().'文件：'.$e->getFile().'行号：'.$e->getLine().'文件栈：'.$e->getTraceAsString()];
            Db::table('xh_sell_refund_log')->where('id', $id)->update($err);
        }
    }
    /**
     * 分销订单-更新佣金信息
     * 该方法用于根据销售信息更新用户的佣金（冻结金额和余额）
     * 包括一级和二级佣金的分配，并记录相关日志
     * belongs_popu_user_id
     * @param array $resInfo 包含销售相关信息的数组，用于更新佣金
     */
    public static function updateCommission($resInfo)
    {
        $logType = '分销订单收益';
        try {
            Db::startTrans();  // 开始事务
            if (empty($resInfo['earnings_level_one'])) {
                // 非推广用户下单，没有收益，直接返回
                return ['code'=>1, 'msg'=>'上级收益为0：非推广用户下单，没有收益，直接返回'];
            }
            $times = date('Y-m-d H:i:s',time()); // 记录变更时间
            // 获取用户当前信息
            $user = Db::table('xh_sell_user')->where('id', $resInfo['user_id'])->find(); //自身用户信息
            if ($user['is_popu_lever'] > 0) {
                // 推广员支付, 自身先收益
                /** 自身收益 开始 */
                //冻结金额累加
                Db::table('xh_sell_user')->where('id', $user['id'])->inc('money_freeze', $resInfo['earnings_level_one'])->update();
                //余额累加
                Db::table('xh_sell_user')->where('id', $user['id'])->inc('money_balance', $resInfo['earnings_level_one'])->update();
                //总收益累加
                Db::table('xh_sell_user')->where('id', $user['id'])->inc('money_total', $resInfo['earnings_level_one'])->update();

                // 构建日志描述
                $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】一级推广员【'.$resInfo['popu_name'].'】下单，自身收益【'.($resInfo['earnings_level_one']/100).'】元';

                // 构建变更详情数组-自身
                $change_json = [
                    [
                        'field' => 'money_balance',
                        'former' => $user['money_balance'],
                        'after' => $user['money_balance'] + $resInfo['earnings_level_one']
                    ],
                    [
                        'field' => 'money_freeze',
                        'former' => $user['money_freeze'],
                        'after' => $user['money_freeze'] + $resInfo['earnings_level_one']
                    ],
                ];
                // 构建日志数据
                $data = [
                    'user_id'=>$resInfo['user_id'],
                    'type'=>$logType,
                    'desc'=>$desc,
                    'remark'=> '一级推广员下单，自身收益',
                    'change_json'=> json_encode($change_json),
                    'change_money'=>$resInfo['earnings_level_one'],
                    'change_time'=>$times,
                    'order_no'=>$resInfo['order_no'],
                ];
                Db::table('xh_sell_user_money_log')->insert($data);  // 插入自身收益日志记录
                /** 自身收益 结束 */
                
                if ($user['is_popu_lever'] == 2){
                    // 二级推广员支付的上级收益
                    /** 上级收益 开始 */
                    $superior = Db::table('xh_sell_popu_user')->where('id', $resInfo['belongs_popu_user_id'])->find(); //上级推广员用户ID
                    $superiorUser = Db::table('xh_sell_user')->where('id', $superior['popu_user_id'])->find(); //上级用户信息
                    //冻结金额累加
                    Db::table('xh_sell_user')->where('id', $superior['id'])->inc('money_freeze', $resInfo['earnings_level_two'])->update();
                    //余额累加
                    Db::table('xh_sell_user')->where('id', $superior['id'])->inc('money_balance', $resInfo['earnings_level_two'])->update();
                    //总收益累加
                    Db::table('xh_sell_user')->where('id', $superior['id'])->inc('money_total', $resInfo['earnings_level_two'])->update();
                    
                    // 构建日志描述
                    $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】二级推广员【'.$resInfo['popu_name'].'】下单，上级【'.$superior['popu_name'].'】收益【'.($resInfo['earnings_level_two']/100).'】元';

                    // 构建变更详情数组-上级
                    $superior_change_json = [
                        [
                            'field' => 'money_balance',
                            'former' => $superiorUser['money_balance'],
                            'after' => $superiorUser['money_balance'] + $resInfo['earnings_level_two']
                        ],
                        [
                            'field' => 'money_freeze',
                            'former' => $superiorUser['money_freeze'],
                            'after' => $superiorUser['money_freeze'] + $resInfo['earnings_level_two']
                        ],
                    ];
                    // 构建日志数据-上级
                    $superior_data = [
                        'user_id'=> $superiorUser['id'],
                        'type'=>$logType,
                        'desc'=>$desc,
                        'remark'=> '一级推广员下单，自身收益',
                        'change_json'=> json_encode($superior_change_json),
                        'change_money'=>$resInfo['earnings_level_two'],
                        'change_time'=>$times,
                        'order_no'=>$resInfo['order_no'],
                    ];
                    Db::table('xh_sell_user_money_log')->insert($superior_data);  // 插入上级收益日志记录
                    /** 上级收益 结束 */
                }
            } else {
                // 用户支付，上级收益
                // 上级一级推广员收益
                /** 上级收益 开始 */
                $superior = Db::table('xh_sell_popu_user')->where('id', $resInfo['popu_user_id'])->find(); //上级推广员用户ID
                $superiorUser = Db::table('xh_sell_user')->where('id', $superior['popu_user_id'])->find(); //上级用户信息
                //冻结金额累加
                Db::table('xh_sell_user')->where('id', $superiorUser['id'])->inc('money_freeze', $resInfo['earnings_level_one'])->update();
                //余额累加
                Db::table('xh_sell_user')->where('id', $superiorUser['id'])->inc('money_balance', $resInfo['earnings_level_one'])->update();
                //总收益累加
                Db::table('xh_sell_user')->where('id', $superiorUser['id'])->inc('money_total', $resInfo['earnings_level_one'])->update();

                // 构建日志描述
                $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】用户【'.$user['nickname'].'】下单，上级【'.$superior['popu_name'].'】收益【'.($resInfo['earnings_level_two']/100).'】元';

                // 构建变更详情数组-上级
                $superior_change_json = [
                    [
                        'field' => 'money_balance',
                        'former' => $superiorUser['money_balance'],
                        'after' => $superiorUser['money_balance'] + $resInfo['earnings_level_two']
                    ],
                    [
                        'field' => 'money_freeze',
                        'former' => $superiorUser['money_freeze'],
                        'after' => $superiorUser['money_freeze'] + $resInfo['earnings_level_two']
                    ],
                ];
                // 构建日志数据-上级
                $superior_data = [
                    'user_id'=> $superiorUser['id'],
                    'type'=>$logType,
                    'desc'=>$desc,
                    'remark'=> '一级推广员下单，自身收益',
                    'change_json'=> json_encode($superior_change_json),
                    'change_money'=>$resInfo['earnings_level_two'],
                    'change_time'=>$times,
                    'order_no'=>$resInfo['order_no'],
                ];
                Db::table('xh_sell_user_money_log')->insert($superior_data);  // 插入上级收益日志记录
                /** 上级收益 结束 */
                
                if ($superior['is_popu_lever'] == 2){
                    // 上级二级推广员收益+上上级一级推广员收益
                    /** 上上级收益 开始 */
                    $beforeLast = Db::table('xh_sell_popu_user')->where('id', $superior['invite_user_id'])->find(); //上上级推广员信息
                    $beforeLastUser = Db::table('xh_sell_user')->where('id', $beforeLast['popu_user_id'])->find(); //上上级用户信息
                    //冻结金额累加
                    Db::table('xh_sell_user')->where('id', $beforeLastUser['id'])->inc('money_freeze', $resInfo['earnings_level_two'])->update();
                    //余额累加
                    Db::table('xh_sell_user')->where('id', $beforeLastUser['id'])->inc('money_balance', $resInfo['earnings_level_two'])->update();
                    //总收益累加
                    Db::table('xh_sell_user')->where('id', $beforeLastUser['id'])->inc('money_total', $resInfo['earnings_level_two'])->update();

                    // 构建日志描述
                    $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】用户【'.$user['nickname'].'】下单，上上级【'.$beforeLast['popu_name'].'】收益【'.($resInfo['earnings_level_two']/100).'】元';

                    // 构建变更详情数组-上级
                    $before_last_change_json = [
                        [
                            'field' => 'money_balance',
                            'former' => $beforeLastUser['money_balance'],
                            'after' => $beforeLastUser['money_balance'] + $resInfo['earnings_level_two']
                        ],
                        [
                            'field' => 'money_freeze',
                            'former' => $beforeLastUser['money_freeze'],
                            'after' => $beforeLastUser['money_freeze'] + $resInfo['earnings_level_two']
                        ],
                    ];
                    // 构建日志数据-上级
                    $before_last_data = [
                        'user_id'=> $beforeLastUser['id'],
                        'type'=>$logType,
                        'desc'=>$desc,
                        'remark'=> '一级推广员下单，自身收益',
                        'change_json'=> json_encode($before_last_change_json),
                        'change_money'=>$resInfo['earnings_level_two'],
                        'change_time'=>$times,
                        'order_no'=>$resInfo['order_no'],
                    ];
                    Db::table('xh_sell_user_money_log')->insert($before_last_data);  // 插入上级收益日志记录
                    /** 上上级收益 结束 */
                }
            }
            Db::commit();  // 提交事务
            return ['code'=>0, 'msg'=>'下单佣金分配成功'];
        } catch (\Exception $e){
            Db::rollBack();  // 回滚事务
            // 记录异常日志
            Db::table('xh_sell_sync_order_1_log')->insert([
                'order_no'=>$resInfo['order_no'],
                'order_type'=>0,
                'info'=>$e->getMessage().'行号：'.$e->getLine() . '文件：'.$e->getFile() . '文件栈：' . $e->getTraceAsString(),
                'info_'=>'下单佣金分配',
                'create_time'=>date('Y-m-d H:i:s')
            ]);
            return ['code'=>2, 'msg'=>'下单佣金分配报错'];
        }
    }
    
    /**
     * 拼团订单-更新用户佣金信息
     * 包括一级和二级佣金的分配，并记录相关日志
     * popu_user_id
     * @param array $resInfo 包含销售相关信息的数组，用于更新佣金
     */
    public static function updateGroupsInfo($resInfo)
    {
        $logType = '拼团订单收益';
        try {
            Db::startTrans();  // 开始事务
            if (empty($resInfo['earnings_level_one'])) {
                // 非推广用户下单，没有收益，直接返回
                return ['code'=>1, 'msg'=>'上级收益为0：非推广用户下单，没有收益，直接返回'];
            }
            $times = date('Y-m-d H:i:s',time()); // 记录变更时间
            // 获取用户当前信息
            $user = Db::table('xh_sell_user')->where('id', $resInfo['user_id'])->find(); //自身用户信息
            if ($user['is_popu_lever'] > 0) {
                // 推广员支付, 自身先收益
                /** 自身收益 开始 */
                //冻结金额累加
                Db::table('xh_sell_user')->where('id', $user['id'])->inc('money_freeze', $resInfo['earnings_level_one'])->update();
                //余额累加
                Db::table('xh_sell_user')->where('id', $user['id'])->inc('money_balance', $resInfo['earnings_level_one'])->update();
                //总收益累加
                Db::table('xh_sell_user')->where('id', $user['id'])->inc('money_total', $resInfo['earnings_level_one'])->update();

                // 构建日志描述
                $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】一级推广员【'.$resInfo['popu_name'].'】下单，自身收益【'.($resInfo['earnings_level_one']/100).'】元';

                // 构建变更详情数组-自身
                $change_json = [
                    [
                        'field' => 'money_balance',
                        'former' => $user['money_balance'],
                        'after' => $user['money_balance'] + $resInfo['earnings_level_one']
                    ],
                    [
                        'field' => 'money_freeze',
                        'former' => $user['money_freeze'],
                        'after' => $user['money_freeze'] + $resInfo['earnings_level_one']
                    ],
                ];
                // 构建日志数据
                $data = [
                    'user_id'=>$resInfo['user_id'],
                    'type'=>$logType,
                    'desc'=>$desc,
                    'remark'=> '一级推广员下单，自身收益',
                    'change_json'=> json_encode($change_json),
                    'change_money'=>$resInfo['earnings_level_one'],
                    'change_time'=>$times,
                    'order_no'=>$resInfo['order_no'],
                ];
                Db::table('xh_sell_user_money_log')->insert($data);  // 插入自身收益日志记录
                /** 自身收益 结束 */
                
                if ($user['is_popu_lever'] == 2){
                    // 二级推广员支付的上级收益
                    /** 上级收益 开始 */
                    $superior = Db::table('xh_sell_popu_user')->where('id', $resInfo['popu_user_id'])->find(); //上级推广员用户ID
                    $superiorUser = Db::table('xh_sell_user')->where('id', $superior['popu_user_id'])->find(); //上级用户信息
                    //冻结金额累加
                    Db::table('xh_sell_user')->where('id', $superior['id'])->inc('money_freeze', $resInfo['earnings_level_two'])->update();
                    //余额累加
                    Db::table('xh_sell_user')->where('id', $superior['id'])->inc('money_balance', $resInfo['earnings_level_two'])->update();
                    //总收益累加
                    Db::table('xh_sell_user')->where('id', $superior['id'])->inc('money_total', $resInfo['earnings_level_two'])->update();
                    
                    // 构建日志描述
                    $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】二级推广员【'.$resInfo['popu_name'].'】下单，上级【'.$superior['popu_name'].'】收益【'.($resInfo['earnings_level_two']/100).'】元';

                    // 构建变更详情数组-上级
                    $superior_change_json = [
                        [
                            'field' => 'money_balance',
                            'former' => $superiorUser['money_balance'],
                            'after' => $superiorUser['money_balance'] + $resInfo['earnings_level_two']
                        ],
                        [
                            'field' => 'money_freeze',
                            'former' => $superiorUser['money_freeze'],
                            'after' => $superiorUser['money_freeze'] + $resInfo['earnings_level_two']
                        ],
                    ];
                    // 构建日志数据-上级
                    $superior_data = [
                        'user_id'=> $superiorUser['id'],
                        'type'=>$logType,
                        'desc'=>$desc,
                        'remark'=> '一级推广员下单，自身收益',
                        'change_json'=> json_encode($superior_change_json),
                        'change_money'=>$resInfo['earnings_level_two'],
                        'change_time'=>$times,
                        'order_no'=>$resInfo['order_no'],
                    ];
                    Db::table('xh_sell_user_money_log')->insert($superior_data);  // 插入上级收益日志记录
                    /** 上级收益 结束 */
                }
            } else {
                // 用户支付，上级收益
                // 上级一级推广员收益
                /** 上级收益 开始 */
                $superior = Db::table('xh_sell_popu_user')->where('id', $resInfo['popu_user_id'])->find(); //上级推广员用户ID
                $superiorUser = Db::table('xh_sell_user')->where('id', $superior['popu_user_id'])->find(); //上级用户信息
                //冻结金额累加
                Db::table('xh_sell_user')->where('id', $superiorUser['id'])->inc('money_freeze', $resInfo['earnings_level_one'])->update();
                //余额累加
                Db::table('xh_sell_user')->where('id', $superiorUser['id'])->inc('money_balance', $resInfo['earnings_level_one'])->update();
                //总收益累加
                Db::table('xh_sell_user')->where('id', $superiorUser['id'])->inc('money_total', $resInfo['earnings_level_one'])->update();

                // 构建日志描述
                $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】用户【'.$user['nickname'].'】下单，上级【'.$superior['popu_name'].'】收益【'.($resInfo['earnings_level_two']/100).'】元';

                // 构建变更详情数组-上级
                $superior_change_json = [
                    [
                        'field' => 'money_balance',
                        'former' => $superiorUser['money_balance'],
                        'after' => $superiorUser['money_balance'] + $resInfo['earnings_level_two']
                    ],
                    [
                        'field' => 'money_freeze',
                        'former' => $superiorUser['money_freeze'],
                        'after' => $superiorUser['money_freeze'] + $resInfo['earnings_level_two']
                    ],
                ];
                // 构建日志数据-上级
                $superior_data = [
                    'user_id'=> $superiorUser['id'],
                    'type'=>$logType,
                    'desc'=>$desc,
                    'remark'=> '一级推广员下单，自身收益',
                    'change_json'=> json_encode($superior_change_json),
                    'change_money'=>$resInfo['earnings_level_two'],
                    'change_time'=>$times,
                    'order_no'=>$resInfo['order_no'],
                ];
                Db::table('xh_sell_user_money_log')->insert($superior_data);  // 插入上级收益日志记录
                /** 上级收益 结束 */
                
                if (!empty($superior['is_popu_lever']) && $superior['is_popu_lever'] == 2){
                    // 上级二级推广员收益+上上级一级推广员收益
                    /** 上上级收益 开始 */
                    $beforeLast = Db::table('xh_sell_popu_user')->where('id', $superior['invite_user_id'])->find(); //上上级推广员信息
                    $beforeLastUser = Db::table('xh_sell_user')->where('id', $beforeLast['popu_user_id'])->find(); //上上级用户信息
                    //冻结金额累加
                    Db::table('xh_sell_user')->where('id', $beforeLastUser['id'])->inc('money_freeze', $resInfo['earnings_level_two'])->update();
                    //余额累加
                    Db::table('xh_sell_user')->where('id', $beforeLastUser['id'])->inc('money_balance', $resInfo['earnings_level_two'])->update();
                    //总收益累加
                    Db::table('xh_sell_user')->where('id', $beforeLastUser['id'])->inc('money_total', $resInfo['earnings_level_two'])->update();

                    // 构建日志描述
                    $desc = '【'.$times.'】订单【'.$resInfo['order_no'].'】规格【'.$resInfo['sku_name'].'】价格【'.$resInfo['sku_price'].'】用户【'.$user['nickname'].'】下单，上上级【'.$beforeLast['popu_name'].'】收益【'.($resInfo['earnings_level_two']/100).'】元';

                    // 构建变更详情数组-上级
                    $before_last_change_json = [
                        [
                            'field' => 'money_balance',
                            'former' => $beforeLastUser['money_balance'],
                            'after' => $beforeLastUser['money_balance'] + $resInfo['earnings_level_two']
                        ],
                        [
                            'field' => 'money_freeze',
                            'former' => $beforeLastUser['money_freeze'],
                            'after' => $beforeLastUser['money_freeze'] + $resInfo['earnings_level_two']
                        ],
                    ];
                    // 构建日志数据-上级
                    $before_last_data = [
                        'user_id'=> $beforeLastUser['id'],
                        'type'=>$logType,
                        'desc'=>$desc,
                        'remark'=> '一级推广员下单，自身收益',
                        'change_json'=> json_encode($before_last_change_json),
                        'change_money'=>$resInfo['earnings_level_two'],
                        'change_time'=>$times,
                        'order_no'=>$resInfo['order_no'],
                    ];
                    Db::table('xh_sell_user_money_log')->insert($before_last_data);  // 插入上级收益日志记录
                    /** 上上级收益 结束 */
                }
            }
            Db::commit();  // 提交事务
            return ['code'=>0, 'msg'=>'下单佣金分配成功'];
        } catch (\Exception $e){
            Db::rollBack();  // 回滚事务
            // 记录异常日志
            Db::table('xh_sell_sync_order_1_log')->insert([
                'order_no'=>$resInfo['order_no'],
                'order_type'=>0,
                'info'=>$e->getMessage().'行号：'.$e->getLine() . '文件：'.$e->getFile() . '文件栈：' . $e->getTraceAsString(),
                'info_'=>'下单佣金分配',
                'create_time'=>date('Y-m-d H:i:s')
            ]);
            return ['code'=>2, 'msg'=>'下单佣金分配报错'];
        }
    }
    /**
     * 支付退款回调
     * @return void
     */
    public function refund_notify()
    {
        // 获取微信支付通知的签名、时间戳、随机串等信息
        $inWechatpaySignature = $_SERVER['HTTP_WECHATPAY_SIGNATURE']; // 请根据实际情况获取
        $inWechatpayTimestamp = $_SERVER['HTTP_WECHATPAY_TIMESTAMP']; // 请根据实际情况获取
        $inWechatpaySerial = ''; // 请根据实际情况获取
        $inWechatpayNonce = $_SERVER['HTTP_WECHATPAY_NONCE']; // 请根据实际情况获取
        $inBody = file_get_contents('php://input');
        // 请根据实际情况获取，例如: file_get_contents('php://input');

        // 设置APIv3密钥，用于解密通知内容
        $apiv3Key = 'bd6dde34c6eab25a2bfc5c9ce8e5de37'; // 在商户平台上设置的APIv3密钥

        $platformCertificateFilePath = 'file:///data/mmc/api/app/apiadmin/keys/fuwushang_Keys/wechatpay_1EF4FF0FD715C8F10A4DB17E274CFF531CCC78A4.pem';
        // 根据通知的平台证书序列号，查询本地平台证书文件，
        // 假定为 `/path/to/wechatpay/inWechatpaySerial.pem`
        $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
        // 检查通知时间偏移量，允许5分钟之内的偏移
        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int) $inWechatpayTimestamp);
        $verifiedStatus = Rsa::verify(
        // 构造验签名串
            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
            $inWechatpaySignature,
            $platformPublicKeyInstance
        );
        // 如果时间和签名验证都通过，则进一步处理通知内容
        if ($timeOffsetStatus && $verifiedStatus) {
            // 转换通知的JSON文本消息为PHP Array数组
            $inBodyArray = (array) json_decode($inBody, true);
            // 提取加密的通知内容，并解密
            $ciphertext = $inBodyArray['resource']['ciphertext'];
            $nonce = $inBodyArray['resource']['nonce'];
            $associated_data = $inBodyArray['resource']['associated_data'];
            // 加密文本消息解密
            $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $associated_data);
            $id = Db::table('xh_sell_refund_log')->insertGetId(['info'=>$inBodyResource, 'create_time'=>date('Y-m-d H:i:s')]);
            // 把解密后的文本转换为PHP Array数组
            $inBodyResourceArray = (array) json_decode($inBodyResource, true);
            // 记录解密后的通知内容到文件
            file_put_contents("./refund_notify.txt", date('Y-m-d H:i:s', time()) . '----退款回调通知----' . $inBodyResource . "\n", FILE_APPEND);

            // 处理订单
            self::updateRefundOrder($inBodyResourceArray,$id);
        }
    }
    /**
     * 更新退款订单状态
     * @param $res
     * @param $id
     * @return \think\response\Json|void
     * @throws \DateMalformedStringException
     * @throws \think\db\exception\DbException
     */
    private static function updateRefundOrder($res,$id)
    {
        // 更新退款日志表中的订单号和交易号
        Db::table('xh_sell_refund_log')->where('id', $id)->update(['order_no'=>$res['out_refund_no'],'transaction_id'=>$res['transaction_id']]);
        try {
            // 提取支付响应中的关键信息
            $transaction_id = $res['transaction_id'];
            $out_trade_no = $res['out_trade_no'];
            $trade_state = $res['refund_status']; //退款状态，枚举值：SUCCESS：退款成功;CLOSED：退款关闭;ABNORMAL：退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败

            // 处理支付成功时间，转换为时间戳
            $dateTimeString = $res['success_time'];
            // 创建DateTime对象
            $dateTime = new DateTime($dateTimeString);
            // 设置时区
            $timeZone = new DateTimeZone('Asia/Shanghai'); // 或者使用 '+08:00' 替换
            $dateTime->setTimeZone($timeZone);
            // 转换为时间戳
            $timestamp = $dateTime->getTimestamp(); //支付成功时间
             //判断退款订单是普通订单还是拼团订单
            $refundInfo = Db::table('xh_sell_refund')->where(['order_no'=>$out_trade_no])->find();
            if($refundInfo['order_type'] == 1){
                // 查询订单信息
                $resInfo = Db::table('xh_sell_refund')->alias('a')
                    ->leftJoin('xh_sell_order b', 'a.order_id = b.id')
                    ->leftJoin('xh_sell_user c', 'a.user_id = c.id')
                    ->leftJoin('xh_siyu_sys_member d', 'a.oper_id = d.uid')
                    ->leftJoin('xh_sell_goods e','a.goods_id=e.id')
                    ->where(['a.order_no'=>$out_trade_no])
                    ->where('a.order_type',1)
                    ->field('a.*, b.order_no,b.id as order_id,b.user_id, c.nickname, c.phone, d.nick_name,e.id')
                    ->find();
                $data = [];
                // 如果退款状态为成功，则进行佣金收回和订单状态更新并记录到退款日志里
                if($trade_state == 'SUCCESS'){
                    
                    // 更新订单状态
                    Db::table('xh_sell_refund')->where('order_no', $out_trade_no)->where('order_type',1)->update(['state'=>3,'agreetime'=>date('Y-m-d H:i:s',$timestamp)]);
                    Db::table('xh_sell_order')->where(['order_no', $out_trade_no])->update(['state'=>8]);
                    Db::table('xh_sell_order_pay')->where('order_no', $out_trade_no)->where('type',1)->update(['pay_state'=>2,'refund_price' => $resInfo['price'],'trade_no'=>$transaction_id,'pay_time'=>$timestamp,'update_time'=>date('Y-m-d H:i:s',time())]);
                    echo '{code:"200",message:"成功"}';

                    //同步订单
                    OrderService::syncXhOrder($resInfo['order_id']);
                 
                    // 记录操作日志
                    $data = [
                        'order_no' => $out_trade_no,
                        'name' => $resInfo['nickname'],
                        'phone' => $resInfo['phone'],
                        'price' => $resInfo['price'],
                        'state'=> $trade_state,
                        'user_name' => $resInfo['nick_name'],
                        'create_time' => date('Y-m-d H:i:s', time()),
                        'commission_state' => 1,
                        'remark' => '退款成功，佣金扣除成功',
                        'order_type' => $refundInfo['order_type']

                    ];
                    $updateOrderGoods = [
                        'refund_status' => 3,
                        'refund_id' => $resInfo['id']
                    ];
                    //扣除佣金
                    self::refundCommission($resInfo);
                    //退课
                    self::kouchuLingke($resInfo);
                }else if($trade_state == 'CLOSED'){
                    echo '{code:"FAIL",message:"失败"}';
                    // 记录操作日志
                    $data = [
                        'order_no' => $out_trade_no,
                        'name' => $resInfo['nickname'],
                        'phone' => $resInfo['phone'],
                        'price' => $resInfo['price'],
                        'state'=> $trade_state,
                        'user_name' => $resInfo['nick_name'],
                        'create_time' => date('Y-m-d H:i:s', time()),
                        'commission_state' => 3,
                        'remark' => '退款关闭，原因可能有：1、余额不足导致退款关闭；2、重复发起退款',
                        'order_type' => $refundInfo['order_type']
                        
                    ];
                    $updateOrderGoods = [
                        'refund_status' => 5,
                        'refund_id' => $resInfo['id']
                    ];
                } else if($trade_state == 'ABNORMAL'){
                    echo '{code:"FAIL",message:"失败"}';
                    // 记录操作日志
                    $data = [
                        'order_no' => $out_trade_no,
                        'name' => $resInfo['nickname'],
                        'phone' => $resInfo['phone'],
                        'price' => $resInfo['price'],
                        'state'=> $trade_state,
                        'user_name' => $resInfo['nick_name'],
                        'create_time' => date('Y-m-d H:i:s', time()),
                        'commission_state' => 4,
                        'remark' => '退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往【商户平台—>交易中心】，手动处理此笔退款',
                        'order_type' => $refundInfo['order_type']
                    ];
                    $updateOrderGoods = [
                        'refund_status' => 5,
                        'refund_id' => $resInfo['id']
                    ];
                }
                //修改订单商品表状态
                Db::table('xh_sell_order_goods')->where('order_id',$resInfo['order_id'])->update($updateOrderGoods);
                //记录退款日志
                Db::table('xh_sell_refund_order_log')->insert($data);
                
            }elseif ($refundInfo['order_type'] == 2){ //拼团订单退款
                // 查询订单信息
                $resInfo = Db::table('xh_sell_refund')->alias('a')
                    ->leftJoin('xh_sell_groups_order b', 'a.order_id = b.id')
                    ->leftJoin('xh_sell_user c', 'a.user_id = c.id')
                    ->leftJoin('xh_siyu_sys_member d', 'a.oper_id = d.uid')
                    ->where(['a.order_no'=>$out_trade_no])
                    ->where('a.order_type',2)
                    ->field('a.*, b.order_no,b.id as order_id,b.user_id, c.nickname, c.phone, d.nick_name')
                    ->find();
                $data = [];
                // 如果退款状态为成功，则进行佣金收回和订单状态更新并记录到退款日志里
                if($trade_state == 'SUCCESS'){
                    
                    // 更新订单状态
                    Db::table('xh_sell_refund')->where('order_no',$out_trade_no)->update(['state'=>3,'agreetime'=>date('Y-m-d H:i:s',$timestamp),'update_time'=>date('Y-m-d H:i:s',time())]);
                    Db::table('xh_sell_groups_order')->where('order_no',$out_trade_no)->update(['state'=>8,'updatetime'=>date('Y-m-d H:i:s',time())]);
                    Db::table('xh_sell_groups_order_goods')->where('order_id',$refundInfo['order_id'])->update(['refund_status'=>3,'updatetime'=>date('Y-m-d H:i:s',time())]);
                    Db::table('xh_sell_order_pay')->where('order_no',$out_trade_no)->where('type',2)->update(['pay_state'=>2,'refund_price' => $resInfo['price'],'trade_no'=>$transaction_id,'pay_time'=>$timestamp,'update_time'=>date('Y-m-d H:i:s',time())]);
                    echo '{code:"200",message:"成功"}';

                    // 更新团信息
                    $oid = Db::table('xh_sell_groups_order')->where('order_no',$out_trade_no)->value('id');
                    Db::table('xh_sell_groups_team')->where('order_id', $oid)->update(['is_del' => 1]);  // 删除拼团团员
                    $groupNo = Db::table('xh_sell_groups_team')->where('order_id', $oid)->value('group_no');
                    Db::table('xh_sell_groups')->where('group_no', $groupNo)->dec('join_num')->update();  // 参团人数减1
                    $group = Db::table('xh_sell_groups')->where('group_no', $groupNo)->find();
                    if (empty($group['join_num'])) {
                        // 如果团人数为0，则将团状态改为未成团
                        Db::table('xh_sell_groups')->where('group_no', $groupNo)->update(['state'=>0, 'join_num'=>0]);
                    } else {
                        if ($group['join_num'] < $group['people_num']) {
                            Db::table('xh_sell_groups')->where('group_no', $groupNo)->update(['state'=>1]);
                        }
                    }
                    // 删除用户链接信息
                    $uid = Db::table('xh_sell_groups_order')->where('order_no',$out_trade_no)->value('user_id');
                    Db::table('xh_sell_user')->where('id', $uid)->update(['g_goods_id'=>0,'g_url'=>null, 'g_is'=>1]);

                    //同步订单
                    OrderService::syncXhGroupsOrder($resInfo['order_id']);
                    
                    // 记录操作日志
                    $data = [
                        'order_no' => $out_trade_no,
                        'name' => $resInfo['nickname'],
                        'phone' => $resInfo['phone'],
                        'price' => $resInfo['price'],
                        'state'=> $trade_state,
                        'user_name' => $resInfo['nick_name'],
                        'create_time' => date('Y-m-d H:i:s', time()),
                        'commission_state' => 1,
                        'remark' => '退款成功，佣金扣除成功',
                        'order_type' => $refundInfo['order_type']
                    ];
                    $updateOrderGoods = [
                        'refund_status' => 3,
                        'refund_id' => $resInfo['id']
                    ];
                    //扣除佣金
                    self::refundGroupsCommission($resInfo);
                    //退课
                    self::kouchuLingke($resInfo);
                }else if($trade_state == 'CLOSED'){
                    echo '{code:"FAIL",message:"失败"}';
                    // 记录操作日志
                    $data = [
                        'order_no' => $out_trade_no,
                        'name' => $resInfo['nickname'],
                        'phone' => $resInfo['phone'],
                        'price' => $resInfo['price'],
                        'state'=> $trade_state,
                        'user_name' => $resInfo['nick_name'],
                        'create_time' => date('Y-m-d H:i:s', time()),
                        'commission_state' => 3,
                        'remark' => '退款关闭，原因可能有：1、余额不足导致退款关闭；2、重复发起退款',
                        'order_type' => $refundInfo['order_type']

                    ];
                    $updateOrderGoods = [
                        'refund_status' => 5,
                        'refund_id' => $resInfo['id']
                    ];
                } else if($trade_state == 'ABNORMAL'){
                    echo '{code:"FAIL",message:"失败"}';
                    // 记录操作日志
                    $data = [
                        'order_no' => $out_trade_no,
                        'name' => $resInfo['nickname'],
                        'phone' => $resInfo['phone'],
                        'price' => $resInfo['price'],
                        'state'=> $trade_state,
                        'user_name' => $resInfo['nick_name'],
                        'create_time' => date('Y-m-d H:i:s', time()),
                        'commission_state' => 4,
                        'remark' => '退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往【商户平台—>交易中心】，手动处理此笔退款',
                        'order_type' => $refundInfo['order_type']

                    ];
                    $updateOrderGoods = [
                        'refund_status' => 5,
                        'refund_id' => $resInfo['id']
                    ];
                }
                //修改订单商品表状态
                Db::table('xh_sell_groups_order_goods')->where('order_id',$resInfo['order_id'])->update($updateOrderGoods);
                //记录退款日志
                Db::table('xh_sell_refund_order_log')->insert($data);

            }
            
        } catch (Exception $e) {
            // 返回错误信息
            return Res::error($e->getMessage());
        }
    }
    /**
     * @description 退款后退回佣金
     * @param $resInfo
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private static function refundCommission($resInfo)
    {
        $resOrder = Db::table('xh_sell_order')
            ->where('order_no',$resInfo['order_no'])
            ->find();
        $userInfo = Db::table('xh_sell_user')->where(['id'=>$resInfo['user_id']])->find();
        $popuUserId = Db::table('xh_sell_popu_user')->where('id',$resOrder['belongs_popu_user_id'])->value('popu_user_id');
        //查找上级推广员
        $popuUserInfo = Db::table('xh_sell_user')->where('id',$popuUserId)->find();
        if ($userInfo['is_popu_lever'] == 0 && $popuUserInfo['is_popu_lever'] == 1){
            Db::table('xh_sell_user')->where(['id'=>$popuUserId])->dec('money_balance',$resOrder['earnings_level_one'])->update();
            Db::table('xh_sell_user')->where(['id'=>$popuUserId])->dec('money_pay_await',$resOrder['earnings_level_one'])->update();
        }elseif ($userInfo['is_popu_lever'] == 0 && $popuUserInfo['is_popu_lever'] == 2){
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_balance',$resOrder['earnings_level_two'])->update();
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_pay_await',$resOrder['earnings_level_two'])->update();

        }elseif ($userInfo['is_popu_lever'] == 1){
            Db::table('xh_sell_user')->where(['id'=>$userInfo['id']])->dec('money_balance',$resOrder['earnings_level_one'])->update();
            Db::table('xh_sell_user')->where(['id'=>$userInfo['id']])->dec('money_pay_await',$resOrder['earnings_level_one'])->update();
        }elseif ($userInfo['is_popu_lever'] == 2){
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_balance',$resOrder['earnings_level_two'])->update();
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_pay_await',$resOrder['earnings_level_two'])->update();
        }
        // 记录变更时间
        $times = date('Y-m-d H:i:s',time());

        // 构建日志描述
        $desc = '【'.$times.'】退款订单【'.$resInfo['order_no'].'】价格【'.$resInfo['total_price'].'】推广ID【'.$resInfo['popu_id'].'】扣除佣金【'.$resOrder['earnings_level_one'].'】元';

        // 构建变更详情数组
        $change_json = [
            [
                'field' => 'money_balance',
                'former' => $userInfo['money_balance'],
                'after' => $resInfo['money_balance']
            ],
            [
                'field' => 'money_freeze',
                'former' => $userInfo['money_freeze'],
                'after' => $resInfo['money_freeze']
            ],
        ];
        // 构建日志数据
        $data = [
            'user_id'=>$resInfo['user_id'],
            'type'=>'订单退款',
            'desc'=>$desc,
            'change_json'=> json_encode($change_json),
            'change_money'=>$resOrder['earnings_level_one'],
            'change_time'=>$times,
            'order_no'=>$resInfo['order_no'],
        ];
        // 插入日志记录
        Db::table('xh_sell_user_money_log')->insert($data);
    }
    private static function refundGroupsCommission($resInfo)
    {
        $resOrder = Db::table('xh_sell_groups_order')
            ->where('order_no',$resInfo['order_no'])
            ->find();
        $userInfo = Db::table('xh_sell_user')->where(['id'=>$resInfo['user_id']])->find();
        $popuUserId = Db::table('xh_sell_popu_user')->where('id',$resOrder['popu_user_id'])->value('popu_user_id');
        //查找上级推广员
        $popuUserInfo = Db::table('xh_sell_user')->where('id',$popuUserId)->find();
        if ($userInfo['is_popu_lever'] == 0 && $popuUserInfo['is_popu_lever'] == 1){
            Db::table('xh_sell_user')->where(['id'=>$popuUserId])->dec('money_balance',$resOrder['earnings_level_one'])->update();
            Db::table('xh_sell_user')->where(['id'=>$popuUserId])->dec('money_pay_await',$resOrder['earnings_level_one'])->update();
        }elseif ($userInfo['is_popu_lever'] == 0 && $popuUserInfo['is_popu_lever'] == 2){
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_balance',$resOrder['earnings_level_two'])->update();
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_pay_await',$resOrder['earnings_level_two'])->update();

        }elseif ($userInfo['is_popu_lever'] == 1){
            Db::table('xh_sell_user')->where(['id'=>$userInfo['id']])->dec('money_balance',$resOrder['earnings_level_one'])->update();
            Db::table('xh_sell_user')->where(['id'=>$userInfo['id']])->dec('money_pay_await',$resOrder['earnings_level_one'])->update();
        }elseif ($userInfo['is_popu_lever'] == 2){
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_balance',$resOrder['earnings_level_two'])->update();
            Db::table('xh_sell_user')->where(['id'=>$popuUserInfo['id']])->dec('money_pay_await',$resOrder['earnings_level_two'])->update();
        }
        // 记录变更时间
        $times = date('Y-m-d H:i:s',time());

        // 构建日志描述
        $desc = '【'.$times.'】退款订单【'.$resInfo['order_no'].'】价格【'.$resInfo['total_price'].'】推广ID【'.$resInfo['group_link_id'].'】扣除佣金【'.$resOrder['earnings_level_one'].'】元';

        // 构建变更详情数组
        $change_json = [
            [
                'field' => 'money_balance',
                'former' => $userInfo['money_balance'],
                'after' => $resInfo['money_balance']
            ],
            [
                'field' => 'money_freeze',
                'former' => $userInfo['money_freeze'],
                'after' => $resInfo['money_freeze']
            ],
        ];
        // 构建日志数据
        $data = [
            'user_id'=>$resInfo['user_id'],
            'type'=>'订单退款',
            'desc'=>$desc,
            'change_json'=> json_encode($change_json),
            'change_money'=>$resOrder['earnings_level_one'],
            'change_time'=>$times,
            'order_no'=>$resInfo['order_no'],
        ];
        // 插入日志记录
        Db::table('xh_sell_user_money_log')->insert($data);
    }
    
    /**
     * @description 扣除领课
     * @param $resInfo
     * @return bool|mixed|string
     */
    private static function kouchuLingke($resInfo)
    {
        $url = 'https://mmcapi.maomaochongtongshu.com/apisell/xcx/lingKe';
        $data = [
            'order_no' => $resInfo['order_no']
        ];
        $result = Curl::callWebServer($url, $data, 'POST', false, false);
        return $result;
    }
    
}